#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QTime>
#include <QFile>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    SlotsInit();
    GetAvailablePorts();
    QFile f;
    f.setFileName(QCoreApplication::applicationDirPath()+"/Ubuntu.qss");
    f.open(QFile::ReadOnly);
    QByteArray array=f.readAll();
    this->setStyleSheet(array.toStdString().c_str());

}

MainWindow::~MainWindow()
{
    //释放资源
    ui->tableWidget->setRowCount(0);

    delete ui;
}

void MainWindow::GetAvailablePorts()
{
    for(QSerialPortInfo x:QSerialPortInfo::availablePorts())
        ui->comboBox->addItem(x.portName());
}

void MainWindow::SlotsInit()
{
    connect(ui->pushButton_4,SIGNAL(clicked()),this,SLOT(OpenPort()));
    connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(StartWriteAddr()));
    connect(ui->pushButton_3,SIGNAL(clicked()),this,SLOT(StopWriteAddr()));
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(SetBatteryNumber()));
    connect(ui->spinBox_4,SIGNAL(valueChanged(int)),this,SLOT(FreshDeviceNumber()));
    connect(ui->pushButton_5,SIGNAL(clicked()),this,SLOT(SingleWriteAddress()));
    connect(ui->pushButton_6,SIGNAL(clicked()),this,SLOT(StartWriteAdderNextStep()));
    connect(ui->pushButton_7,SIGNAL(clicked()),this,SLOT(StopNextTimeWriteAddr()));
    connect(ui->pushButton_8,SIGNAL(clicked()),this,SLOT(GoToNextStep()));

    connect(&cjdevice,SIGNAL(Siganl_ToShowValueData(AGroupBattery)),this,SLOT(Slots_ToShowValueData(AGroupBattery)));
    connect(cjdevice.modbus,SIGNAL(output(QByteArray)),this,SLOT(ShowOutPutMessage(QByteArray)));
    connect(&timer,SIGNAL(timeout()),this,SLOT(WriteAdderTimeOut()));
    connect(&nextTimeTimer,SIGNAL(timeout()),this,SLOT(NextTimerTimeOut()));

}

void MainWindow::SetItemOfTableWidget()
{
    for(int i=0;i<=cjdevice.batteryNumber-1;i++)
    {
        for(int j=0;j<=6;j++)
        {
            ui->tableWidget->setItem(i,j,new QTableWidgetItem());
        }
    }
}

void MainWindow::SetContent(int row, int column, QString value)
{
    qDebug()<<row<<column;
    ui->tableWidget->item(row,column)->setText(value);
}

void MainWindow::TextEditAppendText(QString value)
{
    QTime currentTime=QTime::currentTime();
    ui->textEdit->append(currentTime.toString("hh:mm:ss:")+ value);
    ui->textEdit->moveCursor(QTextCursor::End);
}

bool MainWindow::WriteAddr(int addr)
{
    ushort sendValue=0;
    sendValue=((0xfb<<8)&0xff00)|addr;
    bool ret=false;
    cjdevice.SendFc6(1,2306,1,&sendValue);
    //cjdevice.SendFc3(1,50,1,&sendValue,&ret);
    return ret;
}

float MainWindow::ReadVoltage(int addr)
{
    ushort recv[3]={0};
    bool ret=false;
    cjdevice.SendFc3(1,50+3*(addr-1),3,recv,&ret);
    if(ret==false)
        return 0;

    ui->tableWidget->item(addr-1,0)->setText(QString::number(addr));
    OneBattery oneBattery;
    oneBattery.voltage=(float)recv[0]/1000;
    oneBattery.temperature=(float)recv[1]/10;
    oneBattery.NeiZhu=(float)recv[2]/1000;
    ui->tableWidget->item(addr-1,1)->setText(QString::number(oneBattery.voltage,'f',3));
    ui->tableWidget->item(addr-1,2)->setText(QString::number(oneBattery.temperature,'f',1));
    ui->tableWidget->item(addr-1,3)->setText(QString::number(oneBattery.NeiZhu,'f',3));
    return oneBattery.voltage;
}

void MainWindow::ReadCjBatteryNumber()
{
    bool ret=false;
    ushort recv=0;
    cjdevice.SendFc3(1,2001,1,&recv,&ret);
    ui->spinBox_4->setValue(recv);
}

void MainWindow::FreshDeviceNumber()
{
    cjdevice.batteryNumber=ui->spinBox_4->value();
    ui->tableWidget->clearContents();
    ui->tableWidget->setRowCount(ui->spinBox_4->value());
    SetItemOfTableWidget();
}

void MainWindow::SetBatteryNumber()
{
    cjdevice.batteryNumberOld=cjdevice.batteryNumber;
    cjdevice.batteryNumber=ui->spinBox->value();

    ui->tableWidget->clearContents();

    ui->tableWidget->setRowCount(ui->spinBox->value());
    SetItemOfTableWidget();
    ushort value=0;
    value=cjdevice.batteryNumber;
    bool ret=false;
    cjdevice.SendFc16(1,2001,1,&value,&ret);
    qDebug()<<ret;
    ReadCjBatteryNumber();
}




void MainWindow::OpenPort()
{
    qDebug()<<__FUNCTION__;
    if(ui->pushButton_4->text()=="打开端口")
    {
        cjdevice.OpenPort(ui->comboBox->currentText(),ui->comboBox_2->currentText().toInt());
        if(cjdevice.modbus->port.isOpen())
        {
            TextEditAppendText("端口打开成功");
            ui->pushButton_4->setText("关闭端口");
            ReadCjBatteryNumber();
        }
        else
            ui->textEdit->append("端口打开失败");
    }
    else if(ui->pushButton_4->text()=="关闭端口")
    {
        cjdevice.ClosePort();
        if(!cjdevice.modbus->port.isOpen())
        {
            TextEditAppendText("端口关闭成功");
            ui->pushButton_4->setText("打开端口");
        }
    }
}

void MainWindow::Slots_ToShowValueData(AGroupBattery groupBattery)
{
    for(int i=0;i<=cjdevice.batteryNumber-1;i++)
    {
        ui->tableWidget->item(i,0)->setText(QString::number(i+1));
        ui->tableWidget->item(i,1)->setText(QString::number(groupBattery.battery[i].voltage,'f',3));
        ui->tableWidget->item(i,2)->setText(QString::number(groupBattery.battery[i].temperature,'f',1));
        ui->tableWidget->item(i,3)->setText(QString::number(groupBattery.battery[i].NeiZhu,'f',3));

    }
}

void MainWindow::StartWriteAddr()
{
    if(isRunning==true)
    {
        QMessageBox a;
        a.setText("请先停止当前编址");
        a.show();
        a.exec();
        return;
    }
    //要停掉自动刷新
    isRunning=true;
    cjdevice.StopTimer();
    //获取起始地址
    startBatteryNumber=ui->spinBox_2->value();
    currentBatteryNumber=startBatteryNumber;
    for(int i=startBatteryNumber;i<=cjdevice.batteryNumber;i++)
    {
        for(int j=0;j<=6;j++)
        {
            qDebug()<<i<<j;
            ui->tableWidget->item(i-1,j)->setText("");

        }
    }


    //启动定时器驱动进程进行
    if(startBatteryNumber<=cjdevice.batteryNumber)
    {
        ui->pushButton_2->setStyleSheet("background-color: green;");
        timer.start(3000);
    }
    else
    {
        QMessageBox messageBox;
        messageBox.setText("起始电池节数应小于电池节数");
        messageBox.show();
        messageBox.exec();
    }
}

void MainWindow::StopWriteAddr()
{
    timer.stop();
    cjdevice.StartTimer();
    isRunning=false;
    ui->pushButton_2->setStyleSheet("");
    qDebug()<<__FUNCTION__;
}

void MainWindow::WriteAdderTimeOut()
{
    //打印Logo
    TextEditAppendText(QString("开始写地址%0").arg(currentBatteryNumber));
    WriteAddr(currentBatteryNumber);
    QThread::msleep(200);
    WriteAddr(currentBatteryNumber);
    QThread::msleep(200);

    //读电压
    for(int i=0;i<=3;i++)
    {
        QThread::msleep(200);
        //TextEditAppendText(QString("开始读%0电池电压").arg(currentBatteryNumber));
        float readValue=ReadVoltage(currentBatteryNumber);
        QString readString=QString::number(readValue,'f',3);

        if(readString=="0.000")
        {
            ui->tableWidget->item(currentBatteryNumber-1,6)->setText("failed");
            ui->tableWidget->item(currentBatteryNumber-1,6)->setForeground(Qt::red);
        }
        else
        {
            if(currentBatteryNumber>=cjdevice.batteryNumber)
            {
                SendComplete(currentBatteryNumber);
                QThread::msleep(200);
                SendComplete(currentBatteryNumber);
                QThread::msleep(200);
                SendComplete(currentBatteryNumber);

                ui->tableWidget->item(currentBatteryNumber-1,6)->setText("sucess");
                ui->tableWidget->item(currentBatteryNumber-1,6)->setForeground(Qt::green);
                TextEditAppendText("地址连写完成");
                StopWriteAddr();
                QMessageBox a;
                a.setText("编址完成");
                a.show();
                a.exec();
            }
            else
            {
                SendComplete(currentBatteryNumber);
                QThread::msleep(200);
                SendComplete(currentBatteryNumber);
                QThread::msleep(200);
                SendComplete(currentBatteryNumber);

                ui->tableWidget->item(currentBatteryNumber-1,6)->setText("sucess");
                ui->tableWidget->item(currentBatteryNumber-1,6)->setForeground(Qt::green);
                // TextEditAppendText("写地址成功，进行下一节");
                currentBatteryNumber++;
            }
            qDebug()<<currentBatteryNumber;

            QThread::msleep(300);
            break;
        }
    }
}

void MainWindow::SingleWriteAddress()
{
    qDebug()<<__FUNCTION__<<__LINE__;
    if(isRunning==true)
    {
        QMessageBox a;
        a.setText("请先停止当前编址");
        a.show();
        a.exec();
        return;
    }

    if(ui->spinBox_3->value()>cjdevice.batteryNumber)
    {
        QMessageBox a;
        a.setText("地址超出电池总节数范围");
        a.show();
        a.exec();
        return;
    }

    for(int i=0;i<=6;i++)
        ui->tableWidget->item(ui->spinBox_3->value()-1,i)->setText("");
    //bool ret=false;
    timer.stop();
    qDebug()<<__FUNCTION__<<__LINE__;
    cjdevice.StopTimer();
    qDebug()<<__FUNCTION__<<__LINE__;
    TextEditAppendText(QString("开始写地址%0").arg(ui->spinBox_3->value()));
    qDebug()<<__FUNCTION__<<__LINE__;
    WriteAddr(ui->spinBox_3->value());
    QThread::msleep(200);
    WriteAddr(ui->spinBox_3->value());
    qDebug()<<__FUNCTION__<<__LINE__;

    //读电压
    for(int i=0;i<=3;i++)
    {
        QThread::msleep(300);
        TextEditAppendText("开始读电池电压");
        float readValue=ReadVoltage(ui->spinBox_3->value());
        QString readString=QString::number(readValue,'f',3);
        if(readString=="0.000")
        {
            TextEditAppendText("读取电压值为0");
            ui->tableWidget->item(ui->spinBox_3->value()-1,6)->setText("failed");
            ui->tableWidget->item(ui->spinBox_3->value()-1,6)->setForeground(Qt::red);
        }
        else
        {
            SendComplete(ui->spinBox_3->value());
            QThread::msleep(200);
            SendComplete(ui->spinBox_3->value());
            QThread::msleep(200);
            SendComplete(ui->spinBox_3->value());
            ui->tableWidget->item(ui->spinBox_3->value()-1,6)->setText("Sucess");
            ui->tableWidget->item(ui->spinBox_3->value()-1,6)->setForeground(Qt::green);
            TextEditAppendText("单独写地址成功");

            break;
        }

    }
    cjdevice.StartTimer();
}

void MainWindow::ShowOutPutMessage(QByteArray message)
{
    TextEditAppendText(message.toHex());
}

void MainWindow::SendComplete(int adder)
{
    ushort sendValue=(((0xfc<<8)&0xff00)|adder);
    cjdevice.SendFc6(1,2306,1,&sendValue);
}

void MainWindow::StartWriteAdderNextStep()
{
    if(isRunning==true)
    {
        QMessageBox a;
        a.setText("请先停止当前编址");
        a.show();
        a.exec();
        return;
    }
    for(int i=ui->spinBox_5->value();i<=cjdevice.batteryNumber;i++)
    {
        for(int j=0;j<=6;j++)
        {
            qDebug()<<i<<j;
            ui->tableWidget->item(i-1,j)->setText("");

        }
    }
    cjdevice.StopTimer();
    nextTimeCurrBatNumber=ui->spinBox_5->value();
    ui->label_6->setText(QString::number(nextTimeCurrBatNumber));
    nextTimeTimer.start(2000);
    isRunning=true;
    nextIsSucces=false;
    qDebug()<<__FUNCTION__;
}

void MainWindow::NextTimerTimeOut()
{
    qDebug()<<__FUNCTION__;
    if(ui->tableWidget->rowCount()>=nextTimeCurrBatNumber)
    {
        if(nextIsSucces==false)
        {
            for(int i=0;i<=6;i++)
                ui->tableWidget->item(nextTimeCurrBatNumber-1,i)->setText("");

            TextEditAppendText(QString("开始写地址%0").arg(nextTimeCurrBatNumber));

            WriteAddr(nextTimeCurrBatNumber);
            QThread::msleep(200);
            WriteAddr(nextTimeCurrBatNumber);
            for(int i=0;i<=3;i++)
            {

                TextEditAppendText("开始读电池电压");
                float readValue=ReadVoltage(nextTimeCurrBatNumber);
                QString readString=QString::number(readValue,'f',3);
                if(readString=="0.000")
                {
                    TextEditAppendText("读取电压值为0");
                    ui->tableWidget->item(nextTimeCurrBatNumber-1,6)->setText("failed");
                    ui->tableWidget->item(nextTimeCurrBatNumber-1,6)->setForeground(Qt::red);
                }
                else
                {
                    SendComplete(nextTimeCurrBatNumber);
                    QThread::msleep(200);
                    SendComplete(nextTimeCurrBatNumber);
                    QThread::msleep(200);
                    SendComplete(nextTimeCurrBatNumber);

                    ui->tableWidget->item(nextTimeCurrBatNumber-1,6)->setText("Sucess");
                    ui->tableWidget->item(nextTimeCurrBatNumber-1,6)->setForeground(Qt::green);
                    TextEditAppendText("单独写地址成功");
                    nextIsSucces=true;
                    break;
                }
                QThread::msleep(200);
            }
        }
        else
        {
            qDebug()<<"空等";
        }
    }
    else
    {
        QMessageBox a;
        a.setText("表格行数或电池总节数小于当前电池序号");
        a.exec();
        nextTimeTimer.stop();
        isRunning=false;
        cjdevice.StartTimer();
        return;
    }
}

void MainWindow::StopNextTimeWriteAddr()
{
    qDebug()<<__FUNCTION__;
    nextTimeTimer.stop();
    isRunning=false;
    ui->label_6->setText("0");
    cjdevice.StartTimer();

}

void MainWindow::GoToNextStep()
{
    nextTimeCurrBatNumber++;
    if(nextTimeCurrBatNumber>ui->tableWidget->rowCount())
    {
        nextIsSucces=false;
        StopNextTimeWriteAddr();
        QMessageBox a;
        a.setText("编址完成");
        a.show();
        a.exec();
        return;
    }

    nextIsSucces=false;
    ui->label_6->setText(QString::number(nextTimeCurrBatNumber));

    qDebug()<<__FUNCTION__;
}
